package com.auxgroup.smarthome;


import com.auxgroup.smarthome.utils.ProtocolConvertUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by kevinchen on 2017/9/5.
 *  把数据点的值 转成 字节数组的工具
 *  主要用于saas平台的远程控制指令
 *  奥克斯多联机wifi远程监控通讯协议 Version 1.7 协议a表
 */
public class BusinessDatapointConvertUtils {


    private static final String BC = "0F00";

    private static final int BC1 = 0x0F;

    private static final int BC2 = 0x00;

    private static final int DATA_LENGTH = 0x0f;


    private static final String SRC = "01";

    private static final int SRC1 = 0x01;

    private static final String DST = "01";

    private static final int DST1 = 0x01;

    private static final String[] COMMON_ARR = new String[]{CommonControlFunction.HEAD,CommonControlFunction.CMD,
                                                CommonControlFunction.RET_CMD,BC};

    private static final int [] COMMON_INT_ARR = new int[]{CommonControlFunction.APP2_DEV_NUM,CommonControlFunction.HEAD1,
                                CommonControlFunction.HEAD2,CommonControlFunction.CMD1,CommonControlFunction.CMD2,
                                CommonControlFunction.RET_CMD1,CommonControlFunction.RET_CMD2,BC1,BC2};

    /**
     * key: 所在位置 A-M  value: A-M位置中所包含的对应数据点信息
     */
    private static final Map<String,List<BusinessDatapointControlEnum>> datapointControlEnumMap
            = BusinessDatapointControlEnum.getBusinessDatapointControlEnumMap();

    /**
     * 用于奥克斯多联机wifi控制数据点的原始raw
     * @param dst 设备地址为，支持1-64.
     * @param controlDatapointBusinessValuesMap  key: 数据点名称 value:改变的具体值
     * @return
     */
    private static Pair<String[],int[]> dataPointBusinessConvertRawHexData(int dst, Map<String,String> controlDatapointBusinessValuesMap){
        if(dst < 0 || dst > 64) throw new IllegalArgumentException("地址位控制参数不合法!");
        if (controlDatapointBusinessValuesMap == null || controlDatapointBusinessValuesMap.size() != BusinessDatapointControlEnum.values().length){
            throw new IllegalArgumentException("传入的奥克斯多联机wifi控制的控制参数不合法！");
        }
        String[] hexStrArr = new String[DATA_LENGTH];
        int[] hexNumArr = new int[DATA_LENGTH];
        hexStrArr[0] = SRC;
        hexNumArr[0]=SRC1;
        hexStrArr[1] = String.format("%02x", dst);
        hexNumArr[1]= dst;
        int count = 2;
        for(Iterator<Map.Entry<String, List<BusinessDatapointControlEnum>>> iterator = datapointControlEnumMap.entrySet().iterator();
            iterator.hasNext();){
            Map.Entry<String, List<BusinessDatapointControlEnum>> next = iterator.next();
            List<BusinessDatapointControlEnum> datapointControlEnumList = next.getValue();
            StringBuffer sb = new StringBuffer();
            for(Iterator<BusinessDatapointControlEnum> enumIterator = datapointControlEnumList.iterator();enumIterator.hasNext();){
                BusinessDatapointControlEnum datapointControlEnum = enumIterator.next();
                String name = datapointControlEnum.getName();
                String controlValueStr = controlDatapointBusinessValuesMap.get(name);
                if (StringUtils.isBlank(controlValueStr)){
                    throw new IllegalArgumentException(name+" control value is not empty.");
                }
                int min = datapointControlEnum.getMin();
                int max = datapointControlEnum.getMax();
                Integer controlValue = Integer.parseInt(controlValueStr);
                if( controlValue < min || controlValue > max){
                    throw new IllegalArgumentException(name + " control value should be between " + min
                            + " and " + max+".");
                }
                int bitCount = datapointControlEnum.getBitCount();
                String binaryStr = ProtocolConvertUtils.toBinaryString(controlValue, min, bitCount);
                sb.append(binaryStr);
            }
            String binaryStr = sb.toString();
            String hexStr = ProtocolConvertUtils.converBinaryto2HexStr(binaryStr);
            hexStrArr[count] = hexStr;
            int hexNum = ProtocolConvertUtils.convert2HexStrToDecimal(hexStr);
            hexNumArr[count] = hexNum;
            count++;
        }
        return Pair.of(hexStrArr,hexNumArr);
    }


    /**
     * 获取FCC 16进制 字符串
     * FCC = HEAD + CMD + RETCMD + BC + DATA (16进制拼接而成的字符串)
     * @param dataStr
     * @return
     */
    private static String[] getCheckFccHexStrArr(String[] dataStr){
        if (dataStr==null || dataStr.length <= 0){
            throw new IllegalArgumentException();
        }
        String[] data4HexStrArr = ProtocolConvertUtils.constructData4HexStrArr(dataStr);
        return ArrayUtils.addAll(COMMON_ARR, data4HexStrArr);

    }

    /**
     *  奥克斯多联机wifi远程监控通讯协议 Version 1.7 协议a表 最终指令
     * @param dst 设备地址
     * @param controlDatapointValuesMap
     * @return
     */
    public static int[] getBusinessAControlRaw(int dst, Map<String,String> controlDatapointValuesMap){
        Pair<String[], int[]> dataPointConvertBytes = dataPointBusinessConvertRawHexData(dst, controlDatapointValuesMap);
        String[] leftDataHexArr = dataPointConvertBytes.getLeft();
        String[] fccHexStrArr = getCheckFccHexStrArr(leftDataHexArr);
        String fcc = CommonControlFunction.getFCC(fccHexStrArr);
        int[] fccNumArr = ProtocolConvertUtils.getFccNumArr(fcc);
        int[] rightArr = dataPointConvertBytes.getRight();
        int[] addArr = ArrayUtils.addAll(COMMON_INT_ARR, rightArr);
        return ArrayUtils.addAll(addArr,fccNumArr);
    }

}
